﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20170228_GenericQueue
{
    class GenericQueue<T> : IEnumerable where T : class
    {
        private T[] array;
        public int pointerHead;
        public int pointerTail;


        public GenericQueue(int capacity = 5)
        {
            array = new T[capacity];
            pointerHead = -1;
            pointerTail = -1;
        }

        public T this[int index]
        {
            get
            {
                return array[index % array.Length];
            }
            set
            {
                array[index % array.Length] = value;
            }
        }

        public T Pop()
        {
            if (pointerHead == -1)
                return null;
            T element = array[pointerHead];
            array[pointerHead] = null;
            if (pointerHead == 0 && pointerTail == 0)
            {
                pointerHead = -1;
                pointerTail = -1;
            }
            else
            {
                pointerHead++;
                if (pointerHead == array.Length)
                    pointerHead = 0;
            }
            return element;
        }

        public void Push(T element)
        {
            pointerTail++;
            if (pointerTail == 0)
                pointerHead = 0;
            else
            {
                if (pointerTail == array.Length)
                    pointerTail = 0;
                if (pointerTail == pointerHead)
                    pointerHead++;
                if (pointerHead == array.Length)
                    pointerHead = 0;
            }
            array[pointerTail] = element;
        }

        public void Clear()
        {
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = null;
            }
            pointerHead = -1;
            pointerTail = -1;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return array.GetEnumerator();
        }

        public override string ToString()
        {
            StringBuilder res = new StringBuilder();
            foreach (var item in array)
            {
                if (item == null)
                    res.Append("null ");
                else
                    res.Append(item + " ");
            }
            res.Append("\n");

            return res.ToString();
        }
    }
}
